package com.hmall.gateway.routers;


import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;

@Slf4j
@Component
@RequiredArgsConstructor
public class DynamicRouteLoader {

    private  final NacosConfigManager nacosConfigManager;
    private  final RouteDefinitionWriter writer;

    private  final String dataId="gateway-routes.json";
    private  final String group="DEFAULT_GROUP";
    private  final Set<String> routes=new HashSet<>();


    @PostConstruct
    public void initRouteConfigListener() throws NacosException {
        String configInfo = nacosConfigManager.getConfigService()
                .getConfigAndSignListener(dataId, group, 5000, new Listener() {
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }

                    @Override
                    public void receiveConfigInfo(String s) {
                          //监听到变更，更新路由表
                        updateConfigInfo(s);
                    }
                });
        //第一次，也更新
        updateConfigInfo(configInfo);
    }
public void updateConfigInfo(String configInfo) {
        log.debug("监听到路由:{}", configInfo);
    List<RouteDefinition> routeDefinitions = JSONUtil.toList(configInfo, RouteDefinition.class);
    for (String route : routes) {
        writer.delete(Mono.just(route)).subscribe();
    }
    routes.clear();

    for (RouteDefinition routeDefinition : routeDefinitions) {
        writer.save(Mono.just(routeDefinition)).subscribe();
        routes.add(routeDefinition.getId());
    }

}
}
